package cn.maihe.elg.operation.centers.epoint.sanming.channel;

import cn.maihe.elg.operation.centers.epoint.sanming.channel.service.EpointBaohanNoticeChannelService;
import cn.maihe.elg.operation.centers.epoint.sanming.channel.service.EpointGuarantorClaimSettlementChannelService;
import cn.maihe.elg.operation.centers.epoint.sanming.channel.service.EpointGuarantorRevokeChannelService;
import cn.maihe.elg.operation.centers.epoint.sanming.dto.EpointBaseRespDTO;
import cn.maihe.elg.operation.centers.epoint.sanming.dto.channel.EpointBaohanNoticeReqDTO;
import cn.maihe.elg.operation.centers.epoint.sanming.dto.channel.EpointGuaranteeClaimSettlementReqDTO;
import cn.maihe.elg.operation.centers.epoint.sanming.dto.channel.EpointGuaranteeRevokeReqDTO;
import cn.maihe.elg.operation.centers.epoint.sanming.enums.EpointRespCodeEnum;
import cn.maihe.elg.operation.centers.supports.CenterInterfaceService;
import cn.maihe.elg.operation.centers.supports.model.bo.*;
import cn.maihe.elg.operation.config.ZtAccountInfo;
import cn.maihe.elg.operation.model.dto.InnerBaseResp;
import cn.maihe.elg.operation.model.enums.CenterNoEnum;
import cn.maihe.elg.operation.model.enums.RefundOrderStatus;
import cn.maihe.elg.operation.repository.entity.*;
import cn.maihe.elg.operation.service.business.InstitutionService;
import cn.maihe.elg.operation.service.business.ProjectInfoService;
import cn.maihe.elg.operation.service.guarantee.GuaranteeService;
import cn.maihe.elg.operation.service.order.AcceptOrderInfoService;
import cn.maihe.elg.operation.service.order.NoticeRetryInfoService;
import cn.maihe.elg.operation.service.order.RefundOrderInfoService;
import cn.maihe.elg.operation.service.system.impl.OrganizationServiceImpl;
import cn.maihe.elg.operation.utils.DateUtil;
import cn.maihe.elg.operation.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.Date;

/**
 * @Description 南平(新点)公共资源服务中心接口服务实现
 * @Author WJH
 * @Date 2021/05/26
 */
@Service
@Slf4j
public class EpointCenterInterfaceServiceImpl implements CenterInterfaceService {

    @Resource
    private EpointBaohanNoticeChannelService epointBaohanNoticeChannelService;
    @Resource
    private EpointGuarantorRevokeChannelService epointGuarantorRevokeChannelService;
    @Resource
    private EpointGuarantorClaimSettlementChannelService epointGuarantorClaimSettlementChannelService;
    @Resource
    private RefundOrderInfoService refundOrderInfoService;
    @Resource
    private ProjectInfoService projectInfoService;
    @Resource
    private InstitutionService institutionService;
    @Resource
    private ZtAccountInfo ztAccountInfo;
    @Resource
    private OrganizationServiceImpl organizationService;
    @Resource
    private NoticeRetryInfoService noticeRetryInfoService;
    @Resource
    private GuaranteeService guaranteeService;
    @Resource
    private AcceptOrderInfoService acceptOrderInfoService;

    @Override
    public CenterNoEnum getCenterNoEnum() {
        return CenterNoEnum.SANMING_D;
    }

    @Override
    public InnerBaseResp<String> pushGuarantee(PushCenterGuaranteeBo bo) {
        GuaranteeVo vo = bo.getGuaranteeVo();
        String applyStatus = bo.getApplyStatus();
        EpointBaohanNoticeReqDTO reqDTO = new EpointBaohanNoticeReqDTO();
        reqDTO.setApplyno(vo.getCenterOrderId());
        reqDTO.setInstname(vo.getGuarantorName());
        reqDTO.setBaohanno(vo.getGuaranteeNo());
        if(vo.getGuaranteeTime()==null){
            vo.setGuaranteeTime(new Date());
        }
        reqDTO.setGeneratetime(DateUtil.formateDate(vo.getGuaranteeTime(), "yyyy-MM-dd HH:mm:ss"));
        reqDTO.setApplystatus(applyStatus);
        InnerBaseResp<String> innerBaseResp = null;

        AcceptOrderInfoDO acceptOrderInfo = acceptOrderInfoService.getByAcceptOrderNo(vo.getAcceptOrderNo());
        Assert.notNull(acceptOrderInfo, "查无此受理订单记录");
        try {
            EpointBaseRespDTO resp = epointBaohanNoticeChannelService.doRequest(reqDTO);
            if (EpointRespCodeEnum.isSuccess(resp.getCode())) {
                innerBaseResp = InnerBaseResp.success(reqDTO.getBaohanno());
            } else {
                innerBaseResp = InnerBaseResp.error(resp.getMessage());
            }
        } catch (Exception e) {
            log.error("开函结果通知 >> [{}] 异常:{}", getCenterNoEnum().getCenterName(), e.getMessage(), e);
            innerBaseResp = InnerBaseResp.error("通知异常:" + e.getMessage());
        }

        return innerBaseResp;
    }

    @Override
    public InnerBaseResp noticeGuaranteeRevokeResult(GuaranteeRevokeResultBo bo) {
        EpointGuaranteeRevokeReqDTO reqDTO = new EpointGuaranteeRevokeReqDTO();
        reqDTO.setApplyno(bo.getCenterOrderId());
        reqDTO.setBaohanno(bo.getGuaranteeNo());

        GuaranteeDO guarantee = guaranteeService.getGuaranteeByGuaranteeNo(reqDTO.getBaohanno());
        Assert.notNull(guarantee, "查无此保函记录");

        InnerBaseResp<String> innerBaseResp = null;
        try {
            EpointBaseRespDTO resp = epointGuarantorRevokeChannelService.doRequest(reqDTO);
            if (EpointRespCodeEnum.isSuccess(resp.getCode())) {
                //保函编号作为序列号
                innerBaseResp = InnerBaseResp.success(reqDTO.getBaohanno());
            } else {
                innerBaseResp = InnerBaseResp.error(resp.getMessage());
            }
        } catch (Exception e) {
            log.error("保函撤销|退保结果通知 >> [{}] 异常:{}", getCenterNoEnum().getCenterName(), e.getMessage(), e);
            innerBaseResp = InnerBaseResp.error("通知异常:" + e.getMessage());
        }
        return innerBaseResp;
    }

    @Override
    public InnerBaseResp noticeGuaranteeClaimSettlementResult(GuaranteeClaimSettlementResultBo bo) {
        EpointGuaranteeClaimSettlementReqDTO reqDTO = new EpointGuaranteeClaimSettlementReqDTO();
        RefundOrderInfoDO refundOrderInfo = bo.getRefundOrderInfo();
        //原理赔申请接口中的 业务流水号
        reqDTO.setApplyno(refundOrderInfo.getRefundOrderNo());
        reqDTO.setBaohanno(refundOrderInfo.getGuaranteeNo());

        ProjectInfoDO projectInfoDO = projectInfoService.selectById(refundOrderInfo.getProjectId());
        //赔付状态，1待赔付2已赔付3不予赔付9其他
        if (refundOrderInfo.getStatus() == RefundOrderStatus.UNREFUND.getStatus() ||
                refundOrderInfo.getStatus() == RefundOrderStatus.APPROVAL.getStatus()
        ) {
            reqDTO.setCompensatestatus("1");
            reqDTO.setCompensateremark(refundOrderInfo.getRemark());
        } else if (refundOrderInfo.getStatus() == RefundOrderStatus.REFUNDED.getStatus()) {
            reqDTO.setCompensatestatus("2");
            reqDTO.setCompensateremark(refundOrderInfo.getRemark());
        } else if (refundOrderInfo.getStatus() == RefundOrderStatus.REFUSED.getStatus()) {
            reqDTO.setCompensatestatus("3");
            reqDTO.setCompensateremark(refundOrderInfo.getRemark());
        } else {
            reqDTO.setCompensatestatus("9");
            reqDTO.setCompensateremark(refundOrderInfo.getRemark());
        }
        OrganizationDO organization = organizationService.getOrganization(refundOrderInfo.getOrgId());

        reqDTO.setCompensatename(ztAccountInfo.getAccName());
        reqDTO.setCompensateorgnum(organization.getCreditCode());
        reqDTO.setCompensatecontact(organization.getContactName());
        reqDTO.setCompensatecontacttel(organization.getContactTel());
        //还是取值 ztAccountInfo FIXME
        reqDTO.setCompensatebankcode(ztAccountInfo.getAccNo());
        reqDTO.setCompensateopenbank(ztAccountInfo.getOpenBankName());

        reqDTO.setFavoreename(projectInfoDO.getTenderer());
        reqDTO.setFavoreeorgnum(projectInfoDO.getTendererCreditCode());
        reqDTO.setFavoreecontact(projectInfoDO.getTendererContact());
        reqDTO.setFavoreecontacttel(projectInfoDO.getTendererContactTel());
        reqDTO.setFavoreebankcode(projectInfoDO.getTendererBankCode());
        reqDTO.setFavoreeopenbank(projectInfoDO.getTendererBankOpenbank());
        Long claimFenAmt = StringUtils.isBlank(refundOrderInfo.getRefundAmount()) ? refundOrderInfo.getBidBond()
                : Long.valueOf(refundOrderInfo.getRefundAmount());
        reqDTO.setCompensateamount(StringUtil.toYuan(claimFenAmt));

        InnerBaseResp<String> innerBaseResp = null;
        try {
            EpointBaseRespDTO resp = epointGuarantorClaimSettlementChannelService.doRequest(reqDTO);
            if (EpointRespCodeEnum.isSuccess(resp.getCode())) {
                innerBaseResp = InnerBaseResp.success(reqDTO.getBaohanno());
            } else {
                innerBaseResp = InnerBaseResp.error(resp.getMessage());
            }
        } catch (Exception e) {
            log.error("理赔结果通知 >> [{}] 异常:{}", getCenterNoEnum().getCenterName(), e.getMessage(), e);
            innerBaseResp = InnerBaseResp.error("通知异常:" + e.getMessage());
        }
        return innerBaseResp;
    }

    /**
     * 其他中心节点方法，无需处理
     * @param bo
     * @return
     */
    @Override
    public InnerBaseResp<NoticeGuaranteeApplyResultBo> noticePayResult(NoticePayResultBo bo) {
        return InnerBaseResp.success(bo);
//        throw new RuntimeException(getCenterNoEnum().getCenterName() + " 暂未实现 电子保函支付结果通知");
    }
}
